﻿using System.Collections.Generic;
using RG.Common.WPF.Commands;
using Microsoft.Practices.Unity;
using RG.Common;

namespace RG.Common.WPF.Workplaces
{

    public class FrameList
    {
        public string Name { get; set;}
        public string Hint { get; set; }
        public string ImagePath { get; set; }
        public string HyperlinkUrl { get; set; }
        public string HyperlinkText { get; set; }
        public int ItemNumber { get; set; }
    }
    
    [SupportDataBinding]
    public class WorkplaceFrameSelectorVM : IFrameForMultiWorkplace
    {
        public IUnityContainer Cfg { get; set; }

        [Dependency]
        public IWorkplace Workplace { get; set; }

        [AddPropertyChanged("CurList")]
        public FrameGroup FrameItemCur { get; set;}  // текущий список (от него строим List для отображения)

        public List<FrameList> CurList // эту штуку отображаем
        {
            get { return UserFrameToList(FrameItemCur);}
        }

        private readonly List<FrameGroup> historyList;

        [InjectionConstructor] // Конструктор
        public WorkplaceFrameSelectorVM(IUnityContainer cfg, IUserSettings userSettings)
        {
            Cfg = cfg;
            var rootItem = userSettings.UserFrames();
            FrameItemCur = (FrameGroup)rootItem;
            historyList = new List<FrameGroup>();
            SelectCmd = new DelegateCommand<int>(DoSelectItem);
        }

        private List<FrameList> UserFrameToList(FrameGroup item)
        {
            var curList = new List<FrameList>();
            // Если история есть и мы опускаемся на уровень вниз - сделать возврантый элемент
            // Если история не ведёт к самому верхнему уровню и мы поднимаемся на уровень вверх - сделать возвратный элемент
            if ((historyList.Count > 0 && item != historyList[historyList.Count - 1])||
                (historyList.Count > 1 && item == historyList[historyList.Count - 1]))
            {
                var backItem = new FrameList
                                   {
                                       ItemNumber = -1,
                                       Name = "...",
                                       Hint = "На уровень выше",
                                       ImagePath =
                                           "pack://application:,,,/RG.Common.WPF;component/ToolBarImages/back.png",
                                       HyperlinkText = "",
                                       HyperlinkUrl = ""
                                    };
                curList.Add(backItem);
            }
            for (int i = 0; i < item.Childs.Count; i++)
            {
                var lstItem = new FrameList();
                if (item.Childs[i] is FrameGroup)
                    lstItem.ImagePath = "pack://application:,,,/RG.Common.WPF;component/ToolBarImages/open.png";
                else
                    lstItem.ImagePath = "pack://application:,,,/RG.Common.WPF;component/ToolBarImages/gotoDoc.png";
                lstItem.Name = item.Childs[i].Name;
                lstItem.ItemNumber = i;
                lstItem.Hint = item.Childs[i].Hint ?? "";
                lstItem.HyperlinkUrl = item.Childs[i].HyperlinkUrl ?? "";
                lstItem.HyperlinkText = item.Childs[i].HyperlinkText ?? "";
                curList.Add(lstItem);
            }
            return curList;
        }

        // показывает фрейм, беря тип передаваемого фрейма и подсовывая его Workplace'у в метод Show
        private void ShowFrame(FrameSingle fs)
        {
            var presenter = Cfg.Resolve(fs.Type);
            var frame = (IFrameForMultiWorkplace)presenter;
            if (string.IsNullOrEmpty(frame.Name))
                frame.Name = fs.Name;
            // Вызывает IWorkplace.Show(presenter) у текущего Workplace
            var typeofWorkplace = typeof(IWorkplace);
            var methodInfo = typeofWorkplace.GetMethod("Show");
            var genericArguments = new[] { fs.Type };
            var genericMethodInfo = methodInfo.MakeGenericMethod(genericArguments);
            genericMethodInfo.Invoke(Workplace, new[] { presenter });
        }

        #region Команды
        public DelegateCommand<int> SelectCmd { get; set; }

        public void DoSelectItem(int curItem)
        {
            if (historyList.Count > 0 && curItem == -1) // решили поднятся наверх
            {
                FrameItemCur = historyList[historyList.Count - 1]; // достали список из истории
                historyList.Remove(historyList[historyList.Count-1]); // удалили из стории последнюю запись
                return;
            }
            if (FrameItemCur.Childs[curItem] is FrameGroup) // решили пойти вниз, на новый уровень (типа в папку)
            {
                historyList.Add(FrameItemCur); // сохраняем историю для потомков
                FrameItemCur = (FrameGroup)FrameItemCur.Childs[curItem]; // задаём новый список
            }
            else // решили открыть новый фрейм
                ShowFrame((FrameSingle)FrameItemCur.Childs[curItem]);
        } 
        #endregion

        #region Workplace инерфейс

        private string name;
        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
            }
        }

        public bool CanClose
        {
            get { return true; }
        } 
        #endregion

    }
}
